package com.llu.aesAndDes;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class AesTest {

    // 密钥
    private static  String KEY = null;

    /**
     * 获取密钥
     * @param
     * @throws Exception
     */
    public static String getKey() throws Exception {
        if (KEY == null){
            // 创建AES算法的密钥生成器实例
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            // 初始化密钥生成器，指定密钥长度为128位
            keyGenerator.init(128);
            // 生成秘密密钥
            SecretKey secretKey = keyGenerator.generateKey();
            // 获取密钥的编码形式
            byte[] key = secretKey.getEncoded();

            KEY = Base64.getEncoder().encodeToString(key);
            return KEY;
        }else {
            return KEY;
        }
    }
    public static void main(String[] args) throws Exception {


        String encrypt = encrypt("12345你还还哈6", getKey(), "1234567812345678");
        String decrypt = decrypt(encrypt, getKey(), "1234567812345678");

    }

    /**
     * 加密
     * @param plainText 明文
     * @param key 密钥，密钥会经过base64编码
     * @param iv 向量，要是16字节
     * @return base64编码后的结果
     * @throws Exception
     */
    public static String encrypt(String plainText, String key, String iv) throws Exception {

        //======start 准备加密需要的参数 ===
        // 获取密钥的编码形式
        byte[] SecretKey  = Base64.getDecoder().decode(key);
        // 使用初始化向量创建一个IvParameterSpec对象，该对象将作为加密算法的参数
        IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());
        //======end======

        // 创建Cipher对象，指定使用AES算法，CBC模式，并使用PKCS5填充
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

        // 初始化Cipher对象为加密模式，使用给定的密钥和初始化向量
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(SecretKey, "AES"), ivSpec);
        // 将明文数据加密，得到密文字节数组
        byte[] encrypted = cipher.doFinal(plainText.getBytes());
        // 将密文字节数组转换为Base64编码字符串
        String encryptedBase64 = Base64.getEncoder().encodeToString(encrypted);
        // 打印加密后的Base64字符串
        System.out.println("Encrypted (Base64): " + encryptedBase64);
        return encryptedBase64;
    }

    /**
     * 解密
     * @param encryptedText 密文
     * @param key 密钥
     * @param iv 向量
     * @return
     * @throws Exception
     */
    public static String decrypt(String encryptedText, String key, String iv) throws Exception {

        //======start 准备解密需要的参数 ===
        // 获取密钥的编码形式
        byte[] SecretKey  = Base64.getDecoder().decode(key);
        // 使用初始化向量创建一个IvParameterSpec对象，该对象将作为加密算法的参数
        IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());
        //======end======

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(SecretKey, "AES"), ivSpec);
        byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
        System.out.println("Decrypted: " + new String(decrypted));
        return new String(decrypted);
    }
}

